Introduction to Plotly and Dash¶
🔷 What is Plotly?¶
Plotly is a Python graphing library used to create interactive, publication-quality plots. It's built on top of D3.js, React, and Flask. It supports many types of charts like:
Line, Bar, Scatter plots
Pie and Sunburst charts
Choropleth and Mapbox maps
3D charts, Histograms, Heatmaps, and more
🧠 Plotly works well for data science, business analytics, and dashboarding, and is often used within Jupyter Notebooks, web apps, and reports.
!pip install dash
!pip install plotly dash
Requirement already satisfied: dash in c:\users\ashid\anaconda3\lib\site-packages (3.1.1) Requirement already satisfied: Flask<3.2,>=1.0.4 in c:\users\ashid\anaconda3\lib\site-packages (from dash) (3.0.3) Requirement already satisfied: Werkzeug<3.2 in c:\users\ashid\anaconda3\lib\site-packages (from dash) (3.0.3) Requirement already satisfied: plotly>=5.0.0 in c:\users\ashid\anaconda3\lib\site-packages (from dash) (5.24.1) Requirement already satisfied: importlib-metadata in c:\users\ashid\anaconda3\lib\site-packages (from dash) (7.0.1) Requirement already satisfied: typing-extensions>=4.1.1 in c:\users\ashid\anaconda3\lib\site-packages (from dash) (4.11.0) Requirement already satisfied: requests in c:\users\ashid\anaconda3\lib\site-packages (from dash) (2.32.3) Requirement already satisfied: retrying in c:\users\ashid\anaconda3\lib\site-packages (from dash) (1.4.0) Requirement already satisfied: nest-asyncio in c:\users\ashid\anaconda3\lib\site-packages (from dash) (1.6.0) Requirement already satisfied: setuptools in c:\users\ashid\anaconda3\lib\site-packages (from dash) (75.1.0) Requirement already satisfied: Jinja2>=3.1.2 in c:\users\ashid\anaconda3\lib\site-packages (from Flask<3.2,>=1.0.4->dash) (3.1.4) Requirement already satisfied: itsdangerous>=2.1.2 in c:\users\ashid\anaconda3\lib\site-packages (from Flask<3.2,>=1.0.4->dash) (2.2.0) Requirement already satisfied: click>=8.1.3 in c:\users\ashid\anaconda3\lib\site-packages (from Flask<3.2,>=1.0.4->dash) (8.1.7) Requirement already satisfied: blinker>=1.6.2 in c:\users\ashid\anaconda3\lib\site-packages (from Flask<3.2,>=1.0.4->dash) (1.6.2) Requirement already satisfied: tenacity>=6.2.0 in c:\users\ashid\anaconda3\lib\site-packages (from plotly>=5.0.0->dash) (8.2.3) Requirement already satisfied: packaging in c:\users\ashid\anaconda3\lib\site-packages (from plotly>=5.0.0->dash) (24.1) Requirement already satisfied: MarkupSafe>=2.1.1 in c:\users\ashid\anaconda3\lib\site-packages (from Werkzeug<3.2->dash) (2.1.3) Requirement already satisfied: zipp>=0.5 in c:\users\ashid\anaconda3\lib\site-packages (from importlib-metadata->dash) (3.17.0) Requirement already satisfied: charset-normalizer<4,>=2 in c:\users\ashid\anaconda3\lib\site-packages (from requests->dash) (3.3.2) Requirement already satisfied: idna<4,>=2.5 in c:\users\ashid\anaconda3\lib\site-packages (from requests->dash) (3.7) Requirement already satisfied: urllib3<3,>=1.21.1 in c:\users\ashid\anaconda3\lib\site-packages (from requests->dash) (2.2.3) Requirement already satisfied: certifi>=2017.4.17 in c:\users\ashid\anaconda3\lib\site-packages (from requests->dash) (2025.1.31) Requirement already satisfied: colorama in c:\users\ashid\anaconda3\lib\site-packages (from click>=8.1.3->Flask<3.2,>=1.0.4->dash) (0.4.6) Requirement already satisfied: plotly in c:\users\ashid\anaconda3\lib\site-packages (5.24.1) Requirement already satisfied: dash in c:\users\ashid\anaconda3\lib\site-packages (3.1.1) Requirement already satisfied: tenacity>=6.2.0 in c:\users\ashid\anaconda3\lib\site-packages (from plotly) (8.2.3) Requirement already satisfied: packaging in c:\users\ashid\anaconda3\lib\site-packages (from plotly) (24.1) Requirement already satisfied: Flask<3.2,>=1.0.4 in c:\users\ashid\anaconda3\lib\site-packages (from dash) (3.0.3) Requirement already satisfied: Werkzeug<3.2 in c:\users\ashid\anaconda3\lib\site-packages (from dash) (3.0.3) Requirement already satisfied: importlib-metadata in c:\users\ashid\anaconda3\lib\site-packages (from dash) (7.0.1) Requirement already satisfied: typing-extensions>=4.1.1 in c:\users\ashid\anaconda3\lib\site-packages (from dash) (4.11.0) Requirement already satisfied: requests in c:\users\ashid\anaconda3\lib\site-packages (from dash) (2.32.3) Requirement already satisfied: retrying in c:\users\ashid\anaconda3\lib\site-packages (from dash) (1.4.0) Requirement already satisfied: nest-asyncio in c:\users\ashid\anaconda3\lib\site-packages (from dash) (1.6.0) Requirement already satisfied: setuptools in c:\users\ashid\anaconda3\lib\site-packages (from dash) (75.1.0) Requirement already satisfied: Jinja2>=3.1.2 in c:\users\ashid\anaconda3\lib\site-packages (from Flask<3.2,>=1.0.4->dash) (3.1.4) Requirement already satisfied: itsdangerous>=2.1.2 in c:\users\ashid\anaconda3\lib\site-packages (from Flask<3.2,>=1.0.4->dash) (2.2.0) Requirement already satisfied: click>=8.1.3 in c:\users\ashid\anaconda3\lib\site-packages (from Flask<3.2,>=1.0.4->dash) (8.1.7) Requirement already satisfied: blinker>=1.6.2 in c:\users\ashid\anaconda3\lib\site-packages (from Flask<3.2,>=1.0.4->dash) (1.6.2) Requirement already satisfied: MarkupSafe>=2.1.1 in c:\users\ashid\anaconda3\lib\site-packages (from Werkzeug<3.2->dash) (2.1.3) Requirement already satisfied: zipp>=0.5 in c:\users\ashid\anaconda3\lib\site-packages (from importlib-metadata->dash) (3.17.0) Requirement already satisfied: charset-normalizer<4,>=2 in c:\users\ashid\anaconda3\lib\site-packages (from requests->dash) (3.3.2) Requirement already satisfied: idna<4,>=2.5 in c:\users\ashid\anaconda3\lib\site-packages (from requests->dash) (3.7) Requirement already satisfied: urllib3<3,>=1.21.1 in c:\users\ashid\anaconda3\lib\site-packages (from requests->dash) (2.2.3) Requirement already satisfied: certifi>=2017.4.17 in c:\users\ashid\anaconda3\lib\site-packages (from requests->dash) (2025.1.31) Requirement already satisfied: colorama in c:\users\ashid\anaconda3\lib\site-packages (from click>=8.1.3->Flask<3.2,>=1.0.4->dash) (0.4.6)
#Verify installation
import plotly.express as px
import dash
from dash import html
#simple Plotly plot:
import plotly.express as px
df = px.data.gapminder().query("year == 2007")
fig = px.scatter(df, x="gdpPercap", y="lifeExp", size="pop", color="continent", hover_name="country", log_x=True)
fig.show()
🔶 What is Dash?¶
Dash is a Python framework built by Plotly that helps you create interactive web applications with pure Python (no need to know HTML/CSS/JS).
It’s used to create data dashboards where users can:
Filter and explore data dynamically
Interact with charts and tables
Update visuals based on inputs (dropdowns, sliders, buttons)
from dash import Dash, html
app = Dash(__name__)
app.layout = html.Div("Hello!")
if __name__ == '__main__':
app.run(debug=True, port=8052) # Use an unused port
Why Use Interactive Visualizations?¶
| Feature | Benefit |
|---|---|
| 🔍 Zoom, hover, and filter | Explore data in more depth, focus on specific insights |
| 🧠 Data storytelling | Make complex data easier to understand |
| 🧑💼 User-driven insights | Let users explore what's important to them |
| 🖥️ Dashboards & apps | Create real-time, dynamic visual reporting systems |
| 📊 Multidimensional comparison | Handle more variables (e.g., size, color, animation) in one view |
🧠 Anatomy of a Dash Application¶
A basic Dash app has 3 main components:
1️⃣ Import Packages¶
You need to import Dash core libraries:
import dash
from dash import html, dcc
html→ for layout elements likeDiv,H1,P,Button, etc.dcc(Dash Core Components) → for interactive components likeDropdown,Graph,Slider, etc.
2️⃣ Initialize the App¶
You create a Dash app instance:
app = dash.Dash(__name__)
This sets up the web app and allows you to build its layout and behavior.
3️⃣ Define the Layout¶
The layout is the visual structure (what users see). It's built using nested html and dcc components:
app.layout = html.Div([
html.H1("My First Dash App"),
dcc.Input(id='my-input', value='Hello', type='text'),
html.Div(id='my-output')
])
Every component can have:
id→ used to link input/output callbackschildren→ nested content or text- other properties like
value,style,className, etc.
4️⃣ Add Callbacks (Interactivity)¶
Dash uses callbacks to make the app dynamic.
from dash.dependencies import Input, Output
@app.callback(
Output('my-output', 'children'), # What to update
Input('my-input', 'value') # What triggers the update
)
def update_output(input_value):
return f"You typed: {input_value}"
🌀 This makes the app reactive — the output updates when the input changes.
5️⃣ Run the Server¶
This starts the local web server:
if __name__ == '__main__':
app.run(debug=True) # Use .run(), not .run_server()
📌 Summary:¶
| Part | Purpose |
|---|---|
Import |
Bring in Dash components |
app = dash.Dash(__name__) |
Initializes the app |
app.layout = ... |
Sets the UI structure |
@app.callback |
Adds interactivity |
app.run() |
Runs the web server |
# Full Minimal Dash App Example:
import dash
from dash import html, dcc
from dash.dependencies import Input, Output
app = dash.Dash(__name__)
app.layout = html.Div([
html.H1("Interactive App"),
dcc.Input(id='my-input', value='Dash', type='text'),
html.Div(id='my-output')
])
@app.callback(
Output('my-output', 'children'),
Input('my-input', 'value')
)
def update_output_div(value):
return f'Hello, {value}!'
if __name__ == '__main__':
app.run(debug=True,port=8052)
🧩 Frontend vs Backend — General Concepts¶
| Aspect | Frontend | Backend |
|---|---|---|
| Also known as | Client-side | Server-side |
| Visible to user? | ✅ Yes | ❌ No |
| Built with | HTML, CSS, JavaScript, Dash (html, dcc) |
Python, Flask (in Dash), databases |
| Main job | Displays UI, handles interaction | Handles logic, data processing, APIs |
| Example | Buttons, graphs, dropdowns | Data filtering, ML models, databases |
| Runs where? | In the user's browser | On the server (your computer or web server) |
🔷 In Dash, Both Frontend & Backend Are in Python¶
Dash simplifies full-stack web apps:
- Frontend = built using
dash.htmlanddash.dcccomponents (which get rendered into HTML/JS) - Backend = Python functions (callbacks) that process data, logic, ML models
🧠 Anatomy of Frontend in Dash¶
app.layout = html.Div([
html.H1("My Dashboard"), # Title
dcc.Input(id='user-input', type='text'), # Input field
html.Div(id='output') # Placeholder for dynamic output
])
This is your UI layout — the part users see.
🧠 Anatomy of Backend in Dash¶
@app.callback(
Output('output', 'children'),
Input('user-input', 'value')
)
def process_input(value):
return f"You typed: {value}"
This is your logic — Python code runs on the server, not in the browser.
🔁 Full Cycle (How Frontend & Backend Communicate)¶
- User types into the input (
frontend) - Dash sends the input to the callback function (
backend) - Backend runs Python code and returns output
- Frontend updates automatically — no page reload needed
📌 Summary in Dash Terms¶
| Component | Frontend or Backend? | Role |
|---|---|---|
html.Div, dcc.Input, dcc.Graph |
Frontend | Build interface |
@app.callback functions |
Backend | Handle logic and data |
app.run() |
Backend | Starts web server |
| User sees & clicks | Frontend | Browser |
| Python reacts to inputs | Backend | Server |
#Full Dash App Code (with Frontend & Backend)
import dash
from dash import html, dcc
from dash.dependencies import Input, Output
# ✅ Backend: Create the Dash app
app = dash.Dash(__name__)
# ✅ Frontend: App layout (UI)
app.layout = html.Div([
html.H1("Simple Interactive Dash App"), # Heading
html.Label("Enter your name:"), # Label
dcc.Input(id='name-input', type='text', value='', placeholder='Type here...'),
html.Br(), html.Br(),
html.Div(id='greeting-output') # Output placeholder
])
# ✅ Backend: Callback logic (interactivity)
@app.callback(
Output(component_id='greeting-output', component_property='children'),
Input(component_id='name-input', component_property='value')
)
def update_greeting(name):
if name:
return f"👋 Hello, {name}! Welcome to Dash!"
else:
return "Please enter your name."
# ✅ Backend: Run the server
if __name__ == '__main__':
app.run(debug=True,port=8052)
This app:¶
Has an input box (frontend)
Updates the output text dynamically (backend)
Uses only Python
🔍 Explanation¶
🖼️ Frontend (UI Layout)¶
app.layout = html.Div([...])
- Contains components like
html.H1,dcc.Input, andhtml.Div - What users see and interact with
🧠 Backend (Python Logic)¶
@app.callback(...)
def update_greeting(name):
...
- Handles input logic and generates the response
- Updates the output based on what the user types
✅ To Run This App:¶
- Install Dash (only once):
pip install dash
Save this code in a file like
app.pyRun the app:
python app.py
- Open in your browser:
http://127.0.0.1:8050/
import dash
from dash import html
# Create the app
app = dash.Dash(__name__)
# Define the layout (what the user sees)
app.layout = html.Div("🌍 Hello, World from Dash!")
# Run the app
if __name__ == '__main__':
app.run(debug=True,port=8052)